const Block = function() {
    let blocks = {
        block1: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [1, 1, 1, 1],
            ],
            1: [
                [0, 0, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [1, 1, 1, 1],
            ],
            3: [
                [0, 0, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
            ],
        },
        block2: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 0, 1],
                [0, 1, 1, 1],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 1],
                [0, 1, 0, 0],
            ],
            3: [
                [0, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 0],
            ],
        },
        block3: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 1, 1, 1],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 1],
                [0, 0, 1, 0],
            ],
            3: [
                [0, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
            ],
        },
        block4: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 1, 0],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 1, 0],
            ],
            3: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 1, 1, 0],
            ],
        },
        block5: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 1],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 1],
            ],
            3: [
                [0, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 1, 1, 0],
                [0, 1, 0, 0],
            ],
        },
        block6: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 1],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 0, 1, 0],
                [0, 0, 1, 0],
                [0, 1, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 1, 1, 1],
                [0, 0, 0, 1],
            ],
            3: [
                [ 0, 0, 0, 0],
                [ 0, 1, 1, 0],
                [ 0, 1, 0, 0],
                [ 0, 1, 0, 0],
            ],
        },
        block7: {
            0: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 1, 1],
                [0, 1, 1, 0],
            ],
            1: [
                [0, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
            ],
            2: [
                [0, 0, 0, 0],
                [0, 0, 0, 0],
                [0, 0, 1, 1],
                [0, 1, 1, 0],
            ],
            3: [
                [0, 0, 0, 0],
                [0, 1, 0, 0],
                [0, 1, 1, 0],
                [0, 0, 1, 0],
            ],
        },
    }
    let o = {}
    const randomBlock = function() {
        let keys = Object.keys(blocks)
        let r1 = Math.random() * keys.length
        r1 = Math.ceil(r1) % keys.length
        let key = keys[r1]
        return blocks[key]
    }
    o.state = Math.floor(Math.random() * 4)
    o.color = Math.ceil(Math.random() * 5)
    o.block = randomBlock()
    const sliceBlock = function(arr, n) {
        let result = []
        for (let i = 0; i < arr.length; i++) {
            result.push(arr[i].slice(n))
        }
        return result
    }
    const shrinkArray = function(arr) {
        let l = countEmptyColumnBefore(arr)
        let result = sliceBlock(arr, l)
        return result
    }
    const countEmptyColumnBefore = function(array) {
        let s = 0
        let count = 0
        let oldCount = count
        for (let i = 0; i < array.length; i++) {
            for (let j = 0; j < array[i].length; j++) {
                s += array[j][i]
                if (s !== 0) {
                    oldCount = count
                    s = 0
                    break
                } else if (j === array[i].length - 1) {
                    count += 1
                }
            }
            if (oldCount === count) {
                break
            }
        }
        return count
    }
    o.nextStateCoordinates = function() {
        let nextState = (o.state + 1) % 4
        let nextBlockArray = shrinkArray(o.block[nextState])
        let coordinates = []
        nextBlockArray.forEach((items, i) => {
            items.forEach((item, j) => {
                if (item !== 0) {
                    coordinates.push([i, j])
                }
            })
        })
        return coordinates
    }
    o.assign = (blockObject) => {
        o.color = blockObject.color
        o.state = blockObject.state
        o.block = blockObject.block
    }

    return o
}
